home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
gospeed
/
speed.asm
next >
Wrap
Assembly Source File
|
1990-05-28
|
11KB
|
327 lines
page 58,132
TITLE Go -- Control (and measure) speed for Heath/Zenith PC
; (c) Copyright 1987 David E. Tweten
; All rights reserved. Permission for distribution is granted
; provided that no direct commercial advantage is gained, and
; provided that this copyright notice appears on all copies.
; --------------------------------------------------------------------
;
; Go serves three purposes relating to Dante Bencivengo's "TurboPlus
; V2.0" modification to 4.77 MHz Heath/Zenith PCs. It permits FORMAT
; and VERIFY ON to work. It also permits the user to speed or slow
; the processor. Finally, it measures the processor's speed setting
; (primarily for batch file use). "TurboPlus", the predecessor
; version of "TurboPlus V2.0", was described in the June, 1986 issue
; of REMark, the journal of the Heath/Zenith Users' Group.
;
; Due to a quirk in the diskette BIOS, errors will occur when a track
; format or verify operation is requested at any high speed, or when
; any diskette operation is attempted at 8 MHz. The terminate-and-
; stay-resident portion of this code will prevent the errors from
; occuring by slowing the processor for the duration of the
; operation, unless it is already operating at the slow (4.77 MHz)
; speed.
;
; The optional switch for Go can specify the speed to use when not
; formatting or verifying a floppy disk. It can be "f", which will
; set the clock speed to fast, or it can be "s", which will set the
; clock speed to slow. In any but its initial (TSR installing) call,
; if no switch is given, Go does not change the speed setting. On
; the initial call, if no argument is given, Go assumes "f". Go uses
; whatever switch character is current.
;
; The termination code for Go is set according to the processor speed
; at call, and by whether or not it has previously been called. The
; meaning of its termination code is as follows:
;
; 0 - Go has been called before so the TSR portion is already
; resident. Before the call the clock was set to run at
; 4.77 MHz.
;
; 1 - Go has been called before so the TSR portion is already
; resident. Before the call the clock was set to run at
; its fast speed.
;
; 2 - Go has not been called before. This call installed the TSR
; code and set the clock speed to the specified value (either
; Fast or Slow). If no speed was specified on the call, the
; default of Fast was used.
;
; 3 - Go has been called in error. It did nothing.
;
; NOTE that the actual processor speed is the slower of the speed
; specified and detected by Go, and the speed specified by the
; hardware switch included in the "TurboPlus V2.0". The actual speed
; is indicated by the LED included with the "TurboPlus V2.0" package.
;
; Written by: David E. Tweten <tweten@prandtl.nas.nasa.gov>
;
; 12141 Atrium Drive
; Saratoga, CA 95070
;
; (408) 446-4131
;
; Inspiration: FV.COM, a program of unstated authorship, included on
; the "TurboPlus" software disk.
;
; Modification History:
;
; 1.0 5-10-87 Initial version.
;
; --------------------------------------------------------------------
IGROUP group _TEXT
BLK_HDR_SEGMENT segment at 00000H
blk_flag db ? ; 'M' for normal, 'Z' for final block
blk_owner dw ? ; segment of owner's PSP
blk_psize dw ? ; block size in paragraphs
BLK_HDR_SEGMENT ends
STDOUT equ 1 ; File handle for Standard Output
STDERR equ 2 ; File handle for Standard Error
CR equ 0DH ; ASCII code for Carriage Return
LF equ 0AH ; ASCII code for Line Feed
HT equ 09H ; ASCII code for Horizontal Tab
LEDS equ 0C0H ; Port address of "CPU LEDs"
SLOW equ 1FH ; Turn off all LEDs but "RDY"
FAST equ 3FH ; Turn off all LEDs
VERIFY equ 4 ; Diskette sector verify service number
FORMAT equ 5 ; Format diskette track service number
SUBTTL Resident Interrupt Filter
page
_TEXT segment para public 'CODE'
assume cs:_TEXT,ds:NOTHING,es:NOTHING,ss:NOTHING
org 02CH
env_seg dw ? ; Seg addr for our copy of environment
org 05CH
beg_ovr: ; Beginning of overwritten PSP area
org 080H
istrlen db ? ; Invocation string and length
istring equ $
org 100h
START: jmp go ; Jump around the resident portion.
org 10CH ; Offset in paragraph same as beg_ovr
beg_pr: ; Beginning of part to move into PSP
res_offs equ (beg_pr-beg_ovr) SHR 4 ; Paragraphs to move resident
rom_dsk dd ? ; ROM INT 13 service routine address
speed db FAST ; "Normal" speed, set by command switch
int_13 proc far
pushf ; IF and TF were cleared by the INT 13.
cmp dl,80h ; If it's a Winchester operation,
jae short call_rom ; just go do it.
;
; The following code block is for TurboPlus V2.0 installations running at
; speeds below 8.0 MHz. At 8.0 MHz, all floppy disk operations must be
; performed at low speed. Below 8.0 MHz, only "verify sector" and "format
; track" need to be run at low speed.
;
ifndef MHZ8
cmp ah,VERIFY ; If it's not a verify operation,
je short go_slow
cmp ah,FORMAT ; and it's not a format operation,
jne short call_rom ; just do it.
go_slow:
endif
;
; The previous code block is for TurboPlus V2.0 installations running at
; speeds below 8.0 MHz.
;
popf ; Recover flags at entry, and leave
pushf ; them at stack top for simulated INT.
push ax
mov al,SLOW
out LEDS,al ; Slow to 4.77 MHz.
pop ax
call rom_dsk ; Simulate INT 13 with return here.
push ax
mov al,speed
out LEDS,al ; Resume speed(ing).
pushf ; Put flags where we can get them.
push bp
mov bp,sp
mov ax,[bp+10] ; Extract IF and TF from user's flags,
and ax,300H
or ax,[bp+2] ; merge them with returned flags,
mov [bp+10],ax ; and put them back for the IRET.
pop bp ; Restore the registers,
add sp,+2 ; ignoring the flags.
pop ax
iret ; Return to caller with proper flags.
call_rom:
popf ; Recover flags at entry.
jmp rom_dsk ; Simulate interrupt entry into ROM.
int_13 endp
res_bl equ $-beg_pr ; Length of resident
cod_bl equ $-int_13 ; Length of resident code
SUBTTL Non-resident Code
page
assume ds:_TEXT,es:_TEXT,ss:_TEXT
;
; Non-resident data
;
copyright db "(c) Copyright 1987 David E. Tweten. All rights reserved."
version db "Go version 1.0 installed, for use "
ifdef MHZ8
db "at"
else
db "below"
endif
db " 8.0 MHz.", CR, LF
VERSION_L equ $-version
mes_env db "Warning: can't return environment copy memory.", CR, LF
MES_ENV_L equ $-mes_env
mes_err db "Error: switch value unrecognized.", CR, LF
MES_ERR_L equ $-mes_err
mes_use db "Usage: go [ "
swchar db "*"
db "fs ]", CR, LF
MES_USE_L equ $-mes_use
even
sibling dw ? ; Effective PSP segment addr of twin
go:
cld
mov ax,3700H ; Get switch character
int 21H ; (UNDOCUMENTED MS-DOS FUNCTION).
mov swchar,dl
mov ah,52H ; Get seg. addr. of first memory block
int 21H ; (UNDOCUMENTED MS-DOS FUNCTION).
mov dx,es:[bx-2]
mov sibling,ds ; Initialize PSP seg. addr. to our own.
blkscn:
assume es:BLK_HDR_SEGMENT ; See if we're already installed.
mov es,dx
cmp blk_flag,'Z' ; If we've checked the last block,
je short first ; end this nonsense.
inc dx ; Compute segment address of next
add dx,blk_psize ; block.
mov ax,blk_owner ; Get block owner's PSP segment addr.
sub ax,res_offs ; Modify it to account for our resident
mov es,ax ; code shift.
mov si,offset int_13 ; Get offset for the resident code.
mov di,si
mov cx,cod_bl ; Get resident code byte count.
repe cmpsb ; OK, we've seen the enemy; is he us?
jne blkscn ; If he ain't, keep looking.
mov sibling,es ; Save segment address of our twin.
mov ah,es:speed ; Set our default to our twin's.
first:
assume es:_TEXT
mov dx,ds
mov es,dx
mov si,offset istring ; Initialize argument string pointer
mov cl,istrlen ; and count.
xor ch,ch
whitesp:
jcxz short default ; Skip over leading white space in
lodsb ; argument string.
dec cx
cmp al,' '
je whitesp
cmp al,HT
je whitesp
cmp al,swchar ; If first non-blank is not the switch
jne short badarg ; character, return error.
mov al,[si] ; Get the switch value.
or al,20H ; Force it to lowercase.
mov ah,FAST ; If the switch is "/f", it's fast.
cmp al,'f'
je short found
mov ah,SLOW ; If the switch is "/s", it's slow.
cmp al,'s'
je short found
badarg:
mov ah,40H ; If none of the above, it's an error;
mov dx,offset mes_err ; complain bitterly.
mov cx,MES_ERR_L
mov bx,STDERR
int 21H
error:
mov ah,40H ; Display usage message.
mov dx,offset mes_use
mov cx,MES_USE_L
mov bx,STDERR
int 21H
mov al,3 ; Set return error status.
exit:
mov ah,4ch ; Exit with status.
int 21H
found:
mov al,ah ; Change to the new speed.
out LEDS,al
mov es,sibling ; Note the new default speed.
xchg es:speed,ah
mov dx,ds
mov es,dx
default:
cmp dx,sibling
je short grabint
mov al,0
cmp ah,SLOW
je exit
mov al,1
jmp exit
grabint:
mov ax,3513H ; Get address of diskette (13H)
int 21H ; interrupt response routine.
mov (word ptr rom_dsk)[word * 0],bx ; Move ES:BX to rom_dsk.
mov (word ptr rom_dsk)[word * 1],es
mov ax,cs ; Relocate our resident portion.
mov es,ax
mov si,offset beg_pr
mov di,offset beg_ovr
mov cx,res_bl
rep movsb
mov ax,cs ; Now set new value in the interrupt
sub ax,res_offs ; vector for 13H
mov ds,ax
mov dx,offset int_13
mov ax,2513H ; as int_13.
int 21H
mov ax,cs ; Restore data segment register.
mov ds,ax
mov ah,40H
mov dx,offset version
mov cx,VERSION_L
mov bx,STDOUT
int 21H ; Display the version number.
mov es,env_seg ; Return space for copy of environment.
mov ah,49H
int 21H
jnc short tsr ; If we can't give back the environment
mov ah,40H ; copy, complain (but not bitterly).
mov dx,offset mes_env
mov cx,MES_ENV_L
mov bx,STDERR
int 21H
tsr:
mov dx,di ; Terminate and stay resident.
add dx,15
mov cl,4
shr dx,cl
mov ax,3102H ; Compute size of resident portion in
int 21H ; paragraphs, and leave it behind.
_TEXT ends
end START